/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package visual.Seguridad;

import aentity.aePuntoUbicacion;
import bentity.beEntrada;
import bentity.beOrdenDespacho;
import bentity.bePallet;
import bentity.beProducto;
import bentity.beRack;
import bentity.beUbicacion;
import blogic.blHelper;
import blogic.blUbicacion;
import com.itextpdf.text.BaseColor;
import com.toedter.calendar.JDateChooser;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import javax.swing.JTable;
import java.util.Calendar;

/**
 *
 * @author renzo
 */
public class visualHelper {
    public static void mostrarMensajeError(String mensaje){
        JOptionPane.showMessageDialog(null, mensaje, "Error", JOptionPane.ERROR_MESSAGE);
    }
    public static void mostrarMensajeSatisfaccion(String mensaje){
        JOptionPane.showMessageDialog(null, mensaje, "Información", JOptionPane.INFORMATION_MESSAGE);
    }

    public static int mostrarPreguntaSiNo(String mensaje){
        return JOptionPane.showConfirmDialog(null, mensaje, "Confirmación",JOptionPane.YES_NO_OPTION);
    }

    public static void centrarDialogoEnPantalla(JDialog dialogo){
        int widthScreen = (new JFrame()).getToolkit().getScreenSize().width;
        int heightScreen = (new JFrame()).getToolkit().getScreenSize().height;
        int widthDialog = dialogo.getSize().width;
        int heightDialog = dialogo.getSize().height;
        dialogo.setLocation(widthScreen/2 - widthDialog/2,heightScreen/2 - heightDialog/2);
    }
    public static Date obtenerFechaCalendario(JDateChooser calendario){
        if (calendario.getDate() != null)
                return (new Date(calendario.getDate().getTime()));
        else
            return null;
    }
    public static final int TRANSACCION_FALLIDA = 0;
    public static final int TRANSACCION_EXITOSA = 1;

    public static void soloDigitosEnTextField(KeyEvent evt) {
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/>.<, ";
        if((Character.isLetter(c) && !evt.isAltDown()) || badchars.indexOf(c) > -1) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }



    public static void soloDigitosYPunto(KeyEvent evt){
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/><, ";
        if((Character.isLetter(c) && !evt.isAltDown()) || badchars.indexOf(c) > -1) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void validarTelefono(KeyEvent evt){
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@$%^&_+=\\|\"':;?/><,";
        if((Character.isLetter(c) && !evt.isAltDown()) || badchars.indexOf(c) > -1) {
            evt.consume();
            return;
        }
    }

    public static void soloPuntos(KeyEvent evt) {
        char c = evt.getKeyChar();
        String badchars = "”0123456789¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/><, ";
        if((Character.isLetter(c) && !evt.isAltDown()) || badchars.indexOf(c) > -1) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void ningunCaracterEnTextField(KeyEvent evt) {
        char c = evt.getKeyChar();
        String badchars = "0123456789”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/>.<, ";
        if((Character.isLetter(c) && !evt.isAltDown() || badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void soloDigitosLetrasPuntoComaComilla(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|':;?/><";
        if((badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void soloTexto(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        String badchars = "0123456789”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/>.<, ";
        if((badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void soloTextoyNumeros(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\"':;?/>.<, ";
        if((badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void deshabilitaCtrlV(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        int modif=evt.getModifiers();

        if (c == '\u0016' && modif == KeyEvent.CTRL_MASK) {
                evt.consume();
                return;
        }
    }

 // este metodo lo pueden utilizar para controlar el tamanho 
    public static void controlarTamanho(KeyEvent evt, int tamanho, JTextField texto){
         if(texto.getText().length() > tamanho-1){
             //texto.setEditable(false);
             evt.consume();
        }
       if (evt.getKeyCode() == evt.VK_BACK_SPACE) {
            if (texto.getText().length()== 8){
                texto.setEditable(true);
            }
       }
    }public static void controlarTamanho_V2(KeyEvent evt, int tamanho, JTextArea texto){
         if(texto.getText().length() > tamanho-1){
             //texto.setEditable(false);
             evt.consume();
        }
       if (evt.getKeyCode() == evt.VK_BACK_SPACE) {
            if (texto.getText().length()== 8){
                texto.setEditable(true);
            }
       }
    }



    public static void soloNombres(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|@·~½¬`~!@#$%^&*()_+=\\|\":,;?/><";
        if((badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
    }

    public static void soloEmail(KeyEvent evt) {
        //ESTE METODO PUEDE SERVIR PARA NOMBRES O DESCRIPCIONES.
        char c = evt.getKeyChar();
        String badchars = "”¢€→¶↓“»←«°¡¿{}[]¬|·~½¬`~!#$%^&*()_+=\\|\":,;?/><";
        if((badchars.indexOf(c) > -1)) {
            evt.consume();
            return;
        }
        if(c == '-')
            evt.consume();
    }

    public static void mostrarMensajeAdvertencia(String mensaje) {
        JOptionPane.showMessageDialog(null, mensaje, "Advertencia", JOptionPane.WARNING_MESSAGE);
    }

    public static void pintarAlmacen(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana){
        //ESTE MÉTODO PINTA EL ALMACÉN TOMANDO COMO PARÁMETROS LO SIGUIENTE:
        //- # DE RACKS POR COLUMNA
        //- # DE RACKS POR FILA
        //- # TAMANHO DE CADA RACK
        //- LA ESCALA ES NECESARIA PARA DETERMINAR EL TAMAÑO DEL DIBUJO
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);
        Point puntoCentradoPintado = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        char [][]matriz = blh.obtenerMatrizAlmacen(numCol,numFil,tamanhoRack);
        for(int i=0; i<=numFil; i++){
            for(int j=0; j<=numCol; j++){
                if (matriz[j][i] == '*'){
                    if ((j==0) || (j==(numCol-1)) || (i==0) || (i==(numFil-1)))
                        g.setColor(Color.DARK_GRAY);
                    else
                        g.setColor(Color.BLUE);
                    g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                }
            }
        }
    }

    public static void pintarAlmacenConEntradas(Graphics g, ArrayList<beEntrada> entradas,int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana, Color col){
        //ESTE MÉTODO PINTA EL ALMACÉN TOMANDO COMO PARÁMETROS LO SIGUIENTE:
        //- # DE RACKS POR COLUMNA
        //- # DE RACKS POR FILA
        //- # TAMANHO DE CADA RACK
        //- LA ESCALA ES NECESARIA PARA DETERMINAR EL TAMAÑO DEL DIBUJO
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);
        Point puntoCentradoPintado = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        char [][]matriz = blh.llenarMatrizEntradas(entradas, numCol, numFil, tamanhoRack);
        for(int i=0; i<=numFil; i++){
            for(int j=0; j<=numCol; j++){
                if (matriz[j][i] == '*'){
                    if ((j==0) || (j==(numCol-1)) || (i==0) || (i==(numFil-1)))
                        g.setColor(Color.DARK_GRAY);
                    else
                        g.setColor(col);
                    g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                }
                else{
                    if(matriz[j][i] == 'E'){
                        g.setColor(Color.CYAN);
                        g.fillRect(puntoCentradoPintado.x+j*escala,puntoCentradoPintado.y+i*escala, escala, escala);
                    }
                }
            }
        }
    }

    public static void pintarAlmacenConEntradasSecciones(Graphics g, ArrayList<beEntrada> entradas,int racksPorCol, int racksPorFila, int tamanhoRack, int escala, ArrayList<beRack> racks,Dimension dimVentana, ArrayList<Point> secs, boolean clic){
        //ESTE MÉTODO PINTA EL ALMACÉN TOMANDO COMO PARÁMETROS LO SIGUIENTE:
        //- # DE RACKS POR COLUMNA
        //- # DE RACKS POR FILA
        //- # TAMANHO DE CADA RACK
        //- LA ESCALA ES NECESARIA PARA DETERMINAR EL TAMAÑO DEL DIBUJO
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);
        Point puntoCentradoPintado = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        char [][]matriz = blh.llenarMatrizEntradas(entradas, numCol, numFil, tamanhoRack);
        for (int r=0;r<racks.size();r++){
            int x=2+((((beRack)racks.get(r)).getNumRack())-1)*(tamanhoRack+1);
            int y=racks.get(r).getNumFila();
            if ((y % 2) == 1){
                y = ((y+1)/2)*3-1;
            }
            else {
                y = (y/2)*3;
            }
            for(int j=1; j<=tamanhoRack;j++){
                matriz[x][y]='S';
                x++;
            }
        }
        if (clic ){
            for (int i = 0; i < secs.size(); i++) {
                int ini=secs.get(i).x;
                int y=secs.get(i).y;
                while (matriz[ini-1][y] == '*'){
                    ini-=1;
                }
                for (int x =ini;x<=ini+tamanhoRack-1;x++){
                    matriz[x][y]='T';
                }
            }
        }
        
        for(int i=0; i<=numFil; i++){
            for(int j=0; j<=numCol; j++){
                if (matriz[j][i] == '*'){
                    if ((j==0) || (j==(numCol-1)) || (i==0) || (i==(numFil-1)))
                        g.setColor(Color.DARK_GRAY);
                    else
                        g.setColor(Color.GREEN);
                    g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                }
                else{
                    if(matriz[j][i] == 'E'){
                        g.setColor(Color.CYAN);
                        g.fillRect(puntoCentradoPintado.x+j*escala,puntoCentradoPintado.y+i*escala, escala, escala);
                    }
                    else{
                         if (matriz[j][i] == 'T'){
                            g.setColor(Color.LIGHT_GRAY);
                            g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                        }
                        else{
                            if (matriz[j][i] == 'S'){
                                g.setColor(Color.BLUE);
                                g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                            }
                        }
                    }
                }
                
            }
        }
    }

    public static char [][] llenarMatrizConEstadosUbicaciones(char [][] matriz, boolean clic, ArrayList<beUbicacion>ubs){
        if (clic ){
            for (int i = 0; i < ubs.size(); i++) {
                String est="";
                int x=ubs.get(i).getCoordenadas().getxEnMapa();
                int y=ubs.get(i).getCoordenadas().getyEnMapa();
                try {
                        est = (new blUbicacion()).dameEstado(ubs.get(i).getId_ubicacion());
                } catch (SQLException ex) {
                    Logger.getLogger(visualHelper.class.getName()).log(Level.SEVERE, null, ex);
                }
                
                if (est.equalsIgnoreCase("Disponible")){
                    if (matriz[x][y]=='D'){
                        matriz[x][y]='D';
                    }
                    else
                        matriz[x][y]='M';
                }
                else if(est.equalsIgnoreCase("Ocupado")){
                        if (matriz[x][y]=='O'){
                            matriz[x][y]='O';
                        }
                        else
                            matriz[x][y]='M';
                        }
                        else if(est.equalsIgnoreCase("Reservado")){
                            if (matriz[x][y]=='R'){
                                matriz[x][y]='R';
                            }
                            else
                                matriz[x][y]='M';
                            }
                            else if(est.equalsIgnoreCase("Bloqueado")){
                                if (matriz[x][y]=='B'){
                                    matriz[x][y]='B';
                                }
                                else
                                    matriz[x][y]='M';
                            }

            System.out.println(i);
            }
        }
        return matriz;
    }

    public static void pintarAlmacenConUbicaciones(Graphics g, ArrayList<beEntrada> entradas,int racksPorCol, int racksPorFila, int tamanhoRack, int escala, ArrayList<beRack> racks,Dimension dimVentana,char[][] matriz){
        //ESTE MÉTODO PINTA EL ALMACÉN TOMANDO COMO PARÁMETROS LO SIGUIENTE:
        //- # DE RACKS POR COLUMNA
        //- # DE RACKS POR FILA
        //- # TAMANHO DE CADA RACK
        //- LA ESCALA ES NECESARIA PARA DETERMINAR EL TAMAÑO DEL DIBUJO
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);
        Point puntoCentradoPintado = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        System.out.println(puntoCentradoPintado.x + "  "+puntoCentradoPintado.y);
        
        for(int i=0; i<=numFil; i++){
            for(int j=0; j<=numCol; j++){
                if (matriz[j][i] == '*'){
                    if ((j==0) || (j==(numCol-1)) || (i==0) || (i==(numFil-1)))
                        g.setColor(Color.DARK_GRAY);
                    else
                        g.setColor(Color.GREEN);
                    g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                }
                else{
                    if(matriz[j][i] == 'E'){
                        g.setColor(Color.CYAN);
                        g.fillRect(puntoCentradoPintado.x+j*escala,puntoCentradoPintado.y+i*escala, escala, escala);
                    }
                    else{
                         if (matriz[j][i] == 'T'){
                            g.setColor(Color.LIGHT_GRAY);
                            g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                        }
                        else{
                            if (matriz[j][i] == 'D'){
                                g.setColor(Color.BLUE);
                                g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                            }else{
                                 if (matriz[j][i] == 'O'){
                                    g.setColor(Color.GREEN);
                                    g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                                 }
                                 else{
                                     if (matriz[j][i] == 'R'){
                                        g.setColor(Color.ORANGE);
                                        g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                                     }
                                     else{
                                         if (matriz[j][i] == 'B'){
                                            g.setColor(Color.RED);
                                            g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                                         }else{
                                             if (matriz[j][i] == 'M'){
                                                g.setColor(Color.YELLOW);
                                                g.fillRect(puntoCentradoPintado.x+j*escala, puntoCentradoPintado.y+i*escala, escala, escala);
                                             }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public static Point centrarDibujo(Dimension dimVentana, int numCol, int numFil, int escala){
        Point pto = new Point(0,0);
        pto.x = dimVentana.width/2-numCol*escala/2;
        pto.y = dimVentana.height/2-numFil*escala/2;
        return pto;
    }

    public static void pintarMalla(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana) {
        int numFil = (new blHelper()).calcularNumeroFilas(racksPorCol);
        int numCol = (new blHelper()).calcularNumeroColumnas(racksPorFila, tamanhoRack);
        Point pto = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        g.setColor(Color.BLACK);
        for(int i=0; i<=numFil; i++)//lineas horizontales
            g.drawLine(pto.x, pto.y+i*escala, pto.x+numCol*escala, pto.y+i*escala);

        for(int j=0; j<=numCol; j++)//lineas verticales
           g.drawLine(pto.x+j*escala, pto.y, pto.x+j*escala, pto.y+numFil*escala);
    }

    public static void pintarMallaRack(Graphics g, int pisos, int escala, Dimension dimVentana) {
       
        Point pto = visualHelper.centrarDibujo(dimVentana, 1,pisos, escala);
        g.setColor(Color.BLACK);
        for(int i=0; i<=pisos; i++)//lineas horizontales
            g.drawLine(pto.x, pto.y+i*escala, pto.x+escala, pto.y+i*escala);

        for(int j=0; j<2; j++)//lineas verticales
           g.drawLine(pto.x+j*escala, pto.y, pto.x+j*escala, pto.y+pisos*escala);
    }

    public static void pintarUbsRack(Graphics g, int pisos, int escala, Dimension dimVentana, ArrayList<String> ests) {
          
        Point pto = visualHelper.centrarDibujo(dimVentana, 1, pisos, escala);

        
        for(int i=3; i>=0; i--){//lineas horizontales
            if (ests.get(i).equalsIgnoreCase("Disponible")){
                    g.setColor(Color.GREEN);
                }
                else if(ests.get(i).equalsIgnoreCase("Ocupado")){
                        g.setColor(Color.BLUE);
                        }
                        else if(ests.get(i).equalsIgnoreCase("Reservado")){
                            g.setColor(Color.YELLOW);
                            }
                            else if(ests.get(i).equalsIgnoreCase("Bloqueado")){
                                g.setColor(Color.RED);
                            }
            g.fillRect( pto.x, pto.y+i*escala, escala, escala);
        }
    }

    public static void pintarUbicaciones(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana, ArrayList<beUbicacion> ubicaciones) {
        int numFil = (new blHelper()).calcularNumeroFilas(racksPorCol);
        int numCol = (new blHelper()).calcularNumeroColumnas(racksPorFila, tamanhoRack);
        Point pto = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        int posX = -1;
        int posY = -1;
        for(int i=0; i<ubicaciones.size(); i++){
            posX = ubicaciones.get(i).getCoordenadas().getxEnMapa();
            posY = ubicaciones.get(i).getCoordenadas().getyEnMapa();
            System.out.println("Ubicacion: "+ubicaciones.get(i).getIdUbicacion()+" ("+posX+";"+posY+")");
            g.setColor(Color.RED);
            g.fillRect(pto.x+posX*escala, pto.y+posY*escala, escala, escala);
//            g.setColor(Color.BLACK);
//            g.drawString(String.valueOf(ubicaciones.get(i).getIdUbicacion()), pto.x+posX*escala, pto.y+posY*escala+escala);
        }
    }

    public static void pintarUbicacionesEspecificandoColor(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana, ArrayList<beUbicacion> ubicaciones,Color color) {
        if (ubicaciones==null) return;

        int numFil = (new blHelper()).calcularNumeroFilas(racksPorCol);
        int numCol = (new blHelper()).calcularNumeroColumnas(racksPorFila, tamanhoRack);
        Point pto = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        int posX = -1;
        int posY = -1;
        for(int i=0; i<ubicaciones.size(); i++){
            posX = ubicaciones.get(i).getCoordenadas().getxEnMapa();
            posY = ubicaciones.get(i).getCoordenadas().getyEnMapa();
            System.out.println("Ubicacion: "+ubicaciones.get(i).getIdUbicacion()+" ("+posX+";"+posY+")");
            g.setColor(color);
            g.fillRect(pto.x+posX*escala, pto.y+posY*escala, escala, escala);
//            g.setColor(Color.BLACK);
//            g.drawString(String.valueOf(ubicaciones.get(i).getIdUbicacion()), pto.x+posX*escala, pto.y+posY*escala+escala);
        }
    }

    public static void pintarRutaOptima(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana, ArrayList<aePuntoUbicacion> ptosRutaOptima,BufferStrategy bfs) throws InterruptedException {
        int numFil = (new blHelper()).calcularNumeroFilas(racksPorCol);
        int numCol = (new blHelper()).calcularNumeroColumnas(racksPorFila, tamanhoRack);
        Point pto = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        Point entrada = new Point(ptosRutaOptima.get(0).getCoorX(),ptosRutaOptima.get(0).getCoorY());
        Graphics2D g2d = (Graphics2D)g;
        g2d.setStroke(new BasicStroke(5));
        int posX1 = -1;
        int posY1 = -1;
        int posX2 = -1;
        int posY2 = -1;

        for(int i=0; i<(ptosRutaOptima.size()); i++){
            if (i==(ptosRutaOptima.size())-1){
                posX1 = ptosRutaOptima.get(i).getCoorX();
                posY1 = ptosRutaOptima.get(i).getCoorY();
                if ((posX1 != entrada.x) || (posY1 != entrada.y)){
                    if (ptosRutaOptima.get(i).getIdUbicacion() != -1){
                        if (((posY1+1) % 3)==0)
                            --posY1;
                        else{
                            if ((posY1 % 3)==0)
                                ++posY1;
                        }
                    }
                }
                posX2 = ptosRutaOptima.get(0).getCoorX();
                posY2 = ptosRutaOptima.get(0).getCoorY();
                if ((posX2 != entrada.x) || (posY2 != entrada.y)){
                    if (ptosRutaOptima.get(0).getIdUbicacion() != -1){
                        if (((posY2+1) % 3)==0)
                            --posY2;
                        else{
                            if ((posY2 % 3)==0)
                                ++posY2;
                        }
                    }
                }
            }
            else{
                posX1 = ptosRutaOptima.get(i).getCoorX();
                posY1 = ptosRutaOptima.get(i).getCoorY();
                if ((posX1 != entrada.x) || (posY1 != entrada.y)){
                    if (ptosRutaOptima.get(i).getIdUbicacion() != -1){
                        if (((posY1+1) % 3)==0)
                            --posY1;
                        else{
                            if ((posY1 % 3)==0)
                                ++posY1;
                        }
                    }
                }
                posX2 = ptosRutaOptima.get(i+1).getCoorX();
                posY2 = ptosRutaOptima.get(i+1).getCoorY();
                if ((posX2 != entrada.x) || (posY2 != entrada.y)){
                    if (ptosRutaOptima.get(i+1).getIdUbicacion() != -1){
                        if (((posY2+1) % 3)==0)
                            --posY2;
                        else{
                            if ((posY2 % 3)==0)
                                ++posY2;
                        }
                    }
                }
            }
            g2d.setColor(Color.YELLOW);
            g2d.drawLine(pto.x+posX1*escala+(escala/2), pto.y+posY1*escala+(escala/2), pto.x+posX2*escala+(escala/2), pto.y+posY2*escala+(escala/2));
            g2d.fillOval(pto.x+posX1*escala, pto.y+posY1*escala, escala, escala);
            g2d.fillOval(pto.x+posX2*escala, pto.y+posY2*escala, escala, escala);
//            g2d.setColor(Color.BLACK);
//            g2d.drawString(""+(i+1),pto.x+posX1*escala, pto.y+posY1*escala+escala);
            bfs.show();
        }

        for(int i=0; i<(ptosRutaOptima.size()); i++){
            if (i==(ptosRutaOptima.size())-1){
                posX1 = ptosRutaOptima.get(i).getCoorX();
                posY1 = ptosRutaOptima.get(i).getCoorY();
                if ((posX1 != entrada.x) || (posY1 != entrada.y)){
                    if (ptosRutaOptima.get(i).getIdUbicacion() != -1){
                        if (((posY1+1) % 3)==0)
                            --posY1;
                        else{
                            if ((posY1 % 3)==0)
                                ++posY1;
                        }
                    }
                }
                posX2 = ptosRutaOptima.get(0).getCoorX();
                posY2 = ptosRutaOptima.get(0).getCoorY();
                if ((posX2 != entrada.x) || (posY2 != entrada.y)){
                    if (ptosRutaOptima.get(0).getIdUbicacion() != -1){
                        if (((posY2+1) % 3)==0)
                            --posY2;
                        else{
                            if ((posY2 % 3)==0)
                                ++posY2;
                        }
                    }
                }
            }
            else{
                posX1 = ptosRutaOptima.get(i).getCoorX();
                posY1 = ptosRutaOptima.get(i).getCoorY();
                if ((posX1 != entrada.x) || (posY1 != entrada.y)){
                    if (ptosRutaOptima.get(i).getIdUbicacion() != -1){
                        if (((posY1+1) % 3)==0)
                            --posY1;
                        else{
                            if ((posY1 % 3)==0)
                                ++posY1;
                        }
                    }
                }
                posX2 = ptosRutaOptima.get(i+1).getCoorX();
                posY2 = ptosRutaOptima.get(i+1).getCoorY();
                if ((posX2 != entrada.x) || (posY2 != entrada.y)){
                    if (ptosRutaOptima.get(i+1).getIdUbicacion() != -1){
                        if (((posY2+1) % 3)==0)
                            --posY2;
                        else{
                            if ((posY2 % 3)==0)
                                ++posY2;
                        }
                    }
                }
            }
            g2d.setColor(Color.BLACK);
            g2d.drawLine(pto.x+posX1*escala+(escala/2), pto.y+posY1*escala+(escala/2), pto.x+posX2*escala+(escala/2), pto.y+posY2*escala+(escala/2));
            g2d.fillOval(pto.x+posX1*escala, pto.y+posY1*escala, escala, escala);
            g2d.fillOval(pto.x+posX2*escala, pto.y+posY2*escala, escala, escala);
//            g2d.setColor(Color.BLACK);
//            g2d.drawString(""+(i+1),pto.x+posX1*escala, pto.y+posY1*escala+escala);
            Thread.sleep(1000);
            bfs.show();
        }
    }

    public static void pintarEntradas(Graphics g1, ArrayList<beEntrada> entradas, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana) {
        int numFil = (new blHelper()).calcularNumeroFilas(racksPorCol);
        int numCol = (new blHelper()).calcularNumeroColumnas(racksPorFila, tamanhoRack);
        Point puntoCentradoPintado = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        for(int i=0;i<entradas.size();i++){
            g1.setColor(Color.CYAN);
            g1.fillRect(puntoCentradoPintado.x+entradas.get(i).getPos_x()*escala,puntoCentradoPintado.y+entradas.get(i).getPos_y()*escala, escala, escala);
        }
    }

    public static Point cuadrarBotonEsqInfDer(int tamanhoBoton, Dimension dimVentana){
        Point pto = null;
        if ((dimVentana != null)&&tamanhoBoton>0){
            pto = new Point();
            pto.x = dimVentana.width-tamanhoBoton-20;
            pto.y = dimVentana.height-tamanhoBoton-20;
        }
        return pto;
    }

    public static void crearPDF_ConsultaLog(String direccionDelDocumento,String nombreDocumento, String autor, String empresa,String tituloEnElDocumento, float[] anchos,JTable tablaJava) throws Exception {
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        if (empresa == null)
            document.addAuthor("Sin Nombre");
        else
            document.addAuthor(empresa);

        caratulaPDF(document,tituloEnElDocumento,autor);
        reporteEnPDF_ConsultaLog(document,tablaJava,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF(Document document,String tituloDocumento,String autor) throws Exception {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);

            Paragraph preface2 = new Paragraph();

            preface2=new Paragraph(tituloDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface2, 1);
            lineaVacia(preface2, 1);

            document.add(preface1);
            document.add(preface2);
    }

    private static void reporteEnPDF_ConsultaLog(Document document,JTable tablaJava, float[] anchos) throws Exception {
//INICIO TABLA
        PdfPTable table = new PdfPTable(tablaJava.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tablaJava.getColumnCount();i++){
            p1 = new Phrase(tablaJava.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tablaJava.getRowCount();i++){
            table.addCell(tablaJava.getValueAt(i, 0).toString());
            table.addCell(tablaJava.getValueAt(i, 1).toString());
            table.addCell(tablaJava.getValueAt(i, 2).toString());
            table.addCell(tablaJava.getValueAt(i, 3).toString());
            table.addCell(tablaJava.getValueAt(i, 4).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[4].setHorizontalAlignment(Element.ALIGN_CENTER);
        }
//FIN TABLA
        document.add(table);
    }

    private static void lineaVacia(Paragraph paragraph, int number) {
            for (int i = 0; i < number; i++) {
                    paragraph.add(new Paragraph(" "));
            }
    }

    public static void pintarRotulosPasillosRacksFilas(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Dimension dimVentana){
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);

        Point ptoCentradoPasillosV = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        ptoCentradoPasillosV.x += escala;
        ptoCentradoPasillosV.y -= 30;
        for(int i=0;i<=racksPorFila;i++)
            g.drawString((i+1)+"V", ptoCentradoPasillosV.x+i*(tamanhoRack+1)*escala, ptoCentradoPasillosV.y);

        Point ptoCentradoPasillosH = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        ptoCentradoPasillosH.x -= 70;
        ptoCentradoPasillosH.y += 2*escala;
        for(int i=0;i<=(racksPorCol/2);i++)
            g.drawString((i+1)+"H", ptoCentradoPasillosH.x, ptoCentradoPasillosH.y+i*3*escala);

        Point ptoCentradoFilas = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        ptoCentradoFilas.x -= 30;
        ptoCentradoFilas.y += 3*escala;
        for(int i=0, j=0;i<racksPorCol;i+=2,j++){
            g.drawString("F"+(i+1), ptoCentradoFilas.x, ptoCentradoFilas.y+j*3*escala);
            g.drawString("F"+(i+2), ptoCentradoFilas.x, ptoCentradoFilas.y+j*3*escala+escala);
        }

        Point ptoCentradoRacks = visualHelper.centrarDibujo(dimVentana, numCol, numFil, escala);
        ptoCentradoRacks.x += 2*escala;
        ptoCentradoRacks.y -= 10;
        for(int i=0;i<racksPorFila;i++)
            g.drawString("B"+(i+1), ptoCentradoRacks.x+i*escala*(tamanhoRack+1)+(tamanhoRack/2)*escala, ptoCentradoRacks.y);
    }
    //FUENTES PARA EL PDF
    private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
    private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.NORMAL, BaseColor.RED);
    private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD);
    private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD);

    public static void crearPDF_Trazabilidad(String direccionDelDocumento,String nombreDocumento, String autor, String empresa,String tituloEnElDocumento, float[] anchos, bePallet pallet, JTable tablaJava) throws Exception {
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_Trazabilidad(document,tituloEnElDocumento,autor,pallet,empresa);
        reporteEnPDF_Trazabilidad(document,tablaJava,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF_Trazabilidad(Document document,String tituloDocumento,String autor, bePallet pallet, String empresa) throws Exception {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);
            
            Paragraph preface2 = null;

            preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface2, 1);

            Paragraph preface3 = null;

            preface3=new Paragraph(tituloDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface3.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface3, 1);

            Paragraph preface4 = new Paragraph();
            preface4=new Paragraph("Historial de movimientos del pallet de código "+pallet.getId_Pallet()+" que contiene el producto "+pallet.getDescProducto()+".",FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL));
            preface4.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface4, 1);
            lineaVacia(preface4, 1);

            document.add(preface1);
            document.add(preface2);
            document.add(preface3);
            document.add(preface4);
    }

    private static void reporteEnPDF_Trazabilidad(Document document,JTable tablaJava, float[] anchos) throws Exception {
//INICIO TABLA
        PdfPTable table = new PdfPTable(tablaJava.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tablaJava.getColumnCount();i++){
            p1 = new Phrase(tablaJava.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tablaJava.getRowCount();i++){
            table.addCell(tablaJava.getValueAt(i, 0).toString());
            table.addCell(tablaJava.getValueAt(i, 1).toString());
            table.addCell(tablaJava.getValueAt(i, 2).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[2].setHorizontalAlignment(Element.ALIGN_LEFT);
        }
//FIN TABLA
        document.add(table);
    }

    public static void crearPDF_RutaOptima(String direccionDelDocumento, String nombreDocumento, String autor, String empresa, String tituloEnElDocumento, float[] anchos, beOrdenDespacho ordenDespacho, JTable tblRutaDespacho) throws Exception{
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_RutaOptima(document,tituloEnElDocumento,autor,ordenDespacho,empresa);
        reporteEnPDF_RutaOptima(document,tblRutaDespacho,anchos);
        document.close();

        return;
    }

    private static void reporteEnPDF_RutaOptima(Document document,JTable tablaJava, float[] anchos) throws Exception {
//INICIO TABLA
        PdfPTable table = new PdfPTable(tablaJava.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tablaJava.getColumnCount();i++){
            p1 = new Phrase(tablaJava.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tablaJava.getRowCount();i++){
            table.addCell(tablaJava.getValueAt(i, 0).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_LEFT);
        }
//FIN TABLA
        document.add(table);
    }

    private static void caratulaPDF_RutaOptima(Document document, String tituloEnElDocumento, String autor, beOrdenDespacho ordenDespacho, String empresa) throws Exception{
        Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);

            Paragraph preface2 = null;

            preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface2, 1);

            Paragraph preface3 = null;

            preface3=new Paragraph(tituloEnElDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface3.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface3, 1);

            Paragraph preface4 = new Paragraph();
            preface4=new Paragraph("Ruta óptima para despachar la orden nro. "+ordenDespacho.getIdOrdenDespacho()+".",FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL));
            preface4.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface4, 1);
            lineaVacia(preface4, 1);

            document.add(preface1);
            document.add(preface2);
            document.add(preface3);
            document.add(preface4);
    }

    public static void crearPDF_Inventario(String direccionDelDocumento, String nombreDocumento, String autor, String empresa, String tituloEnElDocumento, float[] anchos, JTable tblRutaDespacho) throws Exception{
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_Inventario(document,tituloEnElDocumento,autor,empresa);
        reporteEnPDF_Inventario(document,tblRutaDespacho,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF_Inventario(Document document, String tituloEnElDocumento, String autor, String empresa) throws Exception{
        Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);

            Paragraph preface2 = new Paragraph();
            preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface2, 1);

            Paragraph preface3 = null;

            preface3=new Paragraph(tituloEnElDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface3.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface3, 1);
            lineaVacia(preface3, 1);

            document.add(preface1);
            document.add(preface2);
            document.add(preface3);
    }

    private static void reporteEnPDF_Inventario(Document document, JTable tblRutaDespacho, float[] anchos) throws Exception{
        //INICIO TABLA
        PdfPTable table = new PdfPTable(tblRutaDespacho.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tblRutaDespacho.getColumnCount();i++){
            p1 = new Phrase(tblRutaDespacho.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tblRutaDespacho.getRowCount();i++){
            table.addCell(tblRutaDespacho.getValueAt(i, 0).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 1).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 2).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 3).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 4).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_LEFT);
            table.getRow(i+1).getCells()[2].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[3].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[4].setHorizontalAlignment(Element.ALIGN_CENTER);
        }
//FIN TABLA
        document.add(table);
    }

    public static void crearPDF_Kardex(String direccionDelDocumento, String nombreDocumento, String autor, String empresa, String tituloEnElDocumento, beProducto producto, float[] anchos, JTable tblRutaDespacho, Date fechaDesde, Date fechaHasta) throws Exception{
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_Kardex(document,tituloEnElDocumento,autor,empresa, producto, fechaDesde, fechaHasta);
        reporteEnPDF_Kardex(document,tblRutaDespacho,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF_Kardex(Document document, String tituloEnElDocumento, String autor, String empresa, beProducto producto, Date fechaDesde, Date fechaHasta) throws Exception{
        Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);

            Paragraph preface2 = new Paragraph();
            preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface2, 1);

            Paragraph preface3 = null;

            preface3=new Paragraph(tituloEnElDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface3.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface3, 1);

            Paragraph preface4 = new Paragraph();
            String strFechas = "";
            if ((fechaDesde == null) && (fechaHasta == null))
                strFechas = "El reporte Kardex no consideró límites de fechas.";
            if ((fechaDesde != null) && (fechaHasta == null))
                strFechas = "El reporte Kardex se consideró desde "+fechaDesde.toString();
            if ((fechaDesde == null) && (fechaHasta != null))
                strFechas = "El reporte Kardex se consideró hasta "+fechaHasta.toString();
            if ((fechaDesde != null) && (fechaHasta != null))
                strFechas = "El reporte Kardex se consideró desde "+fechaDesde.toString()+" hasta "+fechaHasta.toString();
            preface4=new Paragraph(strFechas, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL));
            preface4.setAlignment(Element.ALIGN_LEFT);
            lineaVacia(preface4, 1);
            lineaVacia(preface4, 1);

            document.add(preface1);
            document.add(preface2);
            document.add(preface3);
            document.add(preface4);
    }

    private static void reporteEnPDF_Kardex(Document document, JTable tblRutaDespacho, float[] anchos) throws Exception{
        //INICIO TABLA
        PdfPTable table = new PdfPTable(tblRutaDespacho.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tblRutaDespacho.getColumnCount();i++){
            p1 = new Phrase(tblRutaDespacho.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tblRutaDespacho.getRowCount();i++){
            table.addCell(tblRutaDespacho.getValueAt(i, 0).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 1).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 2).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 3).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 4).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[2].setHorizontalAlignment(Element.ALIGN_LEFT);
            table.getRow(i+1).getCells()[3].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[4].setHorizontalAlignment(Element.ALIGN_CENTER);
        }
//FIN TABLA
        document.add(table);
    }

    public static void crearPDF_Merma(String direccionDelDocumento, String nombreDocumento, String autor, String empresa, String tituloEnElDocumento, float[] anchos, JTable tblRutaDespacho, Date fechaDesde, Date fechaHasta) throws Exception{
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_Merma(document,tituloEnElDocumento,autor,empresa, fechaDesde, fechaHasta);
        reporteEnPDF_Merma(document,tblRutaDespacho,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF_Merma(Document document, String tituloEnElDocumento, String autor, String empresa, Date fechaDesde, Date fechaHasta) throws Exception{
        Calendar calendar = Calendar.getInstance();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

            Paragraph preface1 = new Paragraph();

            preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface1.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface1, 1);

            Paragraph preface2 = new Paragraph();
            preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
            preface2.setAlignment(Element.ALIGN_LEFT);

            lineaVacia(preface2, 1);

            Paragraph preface3 = null;

            preface3=new Paragraph(tituloEnElDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
            preface3.setAlignment(Element.ALIGN_CENTER);

            lineaVacia(preface3, 1);

            Paragraph preface4 = new Paragraph();
            String strFechas = "";
            if ((fechaDesde == null) && (fechaHasta == null))
                strFechas = "El reporte de merma no consideró límites de fechas.";
            if ((fechaDesde != null) && (fechaHasta == null))
                strFechas = "El reporte de merma se consideró desde "+fechaDesde.toString();
            if ((fechaDesde == null) && (fechaHasta != null))
                strFechas = "El reporte de merma se consideró hasta "+fechaHasta.toString();
            if ((fechaDesde != null) && (fechaHasta != null))
                strFechas = "El reporte de merma se consideró desde "+fechaDesde.toString()+" hasta "+fechaHasta.toString();
            preface4=new Paragraph(strFechas, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL));
            preface4.setAlignment(Element.ALIGN_LEFT);
            lineaVacia(preface4, 1);
            lineaVacia(preface4, 1);

            document.add(preface1);
            document.add(preface2);
            document.add(preface3);
            document.add(preface4);
    }

    private static void reporteEnPDF_Merma(Document document, JTable tblRutaDespacho, float[] anchos) throws Exception{
        //INICIO TABLA
        PdfPTable table = new PdfPTable(tblRutaDespacho.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tblRutaDespacho.getColumnCount();i++){
            p1 = new Phrase(tblRutaDespacho.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tblRutaDespacho.getRowCount();i++){
            table.addCell(tblRutaDespacho.getValueAt(i, 0).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 1).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 2).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 3).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 4).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 5).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 6).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[2].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[3].setHorizontalAlignment(Element.ALIGN_LEFT);
            table.getRow(i+1).getCells()[4].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[5].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[6].setHorizontalAlignment(Element.ALIGN_LEFT);
        }
//FIN TABLA
        document.add(table);
    }

    public static void crearPDF_Ingresos(String direccionDelDocumento, String nombreDocumento, String autor, String empresa, String tituloEnElDocumento, Date fechaDesde, Date fechaHasta, float[] anchos, JTable tblRutaDespacho) throws Exception{
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(direccionDelDocumento));
        document.open();
        document.addTitle(nombreDocumento);
        document.addSubject("Using iText");

        document.addKeywords("Java, PDF, iText, NetBeans");
        document.addAuthor(empresa);

        caratulaPDF_Ingresos(document,tituloEnElDocumento,autor,empresa, fechaDesde, fechaHasta);
        reporteEnPDF_Ingresos(document,tblRutaDespacho,anchos);
        document.close();

        return;
    }

    private static void caratulaPDF_Ingresos(Document document, String tituloEnElDocumento, String autor, String empresa, Date fechaDesde, Date fechaHasta) throws Exception{
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

        Paragraph preface1 = new Paragraph();

        preface1=new Paragraph("Reporte elaborado por "+autor+" el dia "+dateFormat.format(calendar.getTime()),FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
        preface1.setAlignment(Element.ALIGN_LEFT);

        lineaVacia(preface1, 1);

        Paragraph preface2 = new Paragraph();
        preface2=new Paragraph("Propiedad de "+empresa, FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL));
        preface2.setAlignment(Element.ALIGN_LEFT);

        lineaVacia(preface2, 1);

        Paragraph preface3 = null;

        preface3=new Paragraph(tituloEnElDocumento,FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, Font.NORMAL));
        preface3.setAlignment(Element.ALIGN_CENTER);

        lineaVacia(preface3, 1);

        Paragraph preface4 = new Paragraph();
        String strFechas = "";
        if ((fechaDesde == null) && (fechaHasta == null))
            strFechas = "El reporte de ingresos no consideró límites de fechas.";
        if ((fechaDesde != null) && (fechaHasta == null))
            strFechas = "El reporte de ingresos se consideró desde "+fechaDesde.toString();
        if ((fechaDesde == null) && (fechaHasta != null))
            strFechas = "El reporte de ingresos se consideró hasta "+fechaHasta.toString();
        if ((fechaDesde != null) && (fechaHasta != null))
            strFechas = "El reporte de ingresos se consideró desde "+fechaDesde.toString()+" hasta "+fechaHasta.toString();
        preface4=new Paragraph(strFechas, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL));
        preface4.setAlignment(Element.ALIGN_LEFT);
        lineaVacia(preface4, 1);
        lineaVacia(preface4, 1);

        document.add(preface1);
        document.add(preface2);
        document.add(preface3);
        document.add(preface4);
    }

    private static void reporteEnPDF_Ingresos(Document document, JTable tblRutaDespacho, float[] anchos) throws Exception{
        //INICIO TABLA
        PdfPTable table = new PdfPTable(tblRutaDespacho.getColumnCount());
        table.setWidthPercentage(95);
        table.setWidths(anchos);

        PdfPCell c1 = null;
        Phrase p1 = null;
        for(int i=0;i<tblRutaDespacho.getColumnCount();i++){
            p1 = new Phrase(tblRutaDespacho.getColumnName(i));
            c1 = new PdfPCell(p1);
            c1.setHorizontalAlignment(Element.ALIGN_CENTER);
            c1.setNoWrap(true);
            c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
            table.addCell(c1);
        }

        table.setHeaderRows(1);

        for(int i=0;i<tblRutaDespacho.getRowCount();i++){
            table.addCell(tblRutaDespacho.getValueAt(i, 0).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 1).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 2).toString());
            table.addCell(tblRutaDespacho.getValueAt(i, 3).toString());
            table.getRow(i+1).getCells()[0].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[1].setHorizontalAlignment(Element.ALIGN_LEFT);
            table.getRow(i+1).getCells()[2].setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getRow(i+1).getCells()[3].setHorizontalAlignment(Element.ALIGN_CENTER);
        }
//FIN TABLA
        document.add(table);
    }

    public static void pintarAlmacenConEntradasCOPIA(Graphics g, ArrayList<beEntrada> entradas,int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Point puntoCentrado,Point puntoInicio,Point puntoFin, Color col) {
        blHelper blh = new blHelper();
        int numCol = blh.calcularNumeroColumnas(racksPorFila,tamanhoRack);
        int numFil = blh.calcularNumeroFilas(racksPorCol);


        char [][]matriz = blh.llenarMatrizEntradas(entradas, numCol, numFil, tamanhoRack);
        for(int i=(puntoInicio.y-puntoCentrado.y)/escala; i<=numFil; i++){
            if(puntoCentrado.y+(i+1)*escala>puntoFin.y) break;

            for(int j=(puntoInicio.x-puntoCentrado.x)/escala; j<=numCol; j++){
                if(puntoCentrado.x+(j+1)*escala>puntoFin.x) continue;

                if (matriz[j][i] == '*'){
                    if ((j==0) || (j==(numCol-1)) || (i==0) || (i==(numFil-1)))
                        g.setColor(Color.DARK_GRAY);
                    else
                        g.setColor(col);
                    g.fillRect(puntoCentrado.x+j*escala, puntoCentrado.y+i*escala, escala, escala);
                }
                else{
                    if(matriz[j][i] == 'E'){
                        g.setColor(Color.CYAN);
                        g.fillRect(puntoCentrado.x+j*escala,puntoCentrado.y+i*escala, escala, escala);
                    }

                }
            }
        }
    }

    public static void pintarUbicacionesEspecificandoColorCOPIA(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Point puntoCentrado,Point puntoInicio,Point puntoFin, ArrayList<beUbicacion> ubicaciones, Color color) {
        if (ubicaciones==null) return;

        int posX = -1;
        int posY = -1;
        for(int i=0; i<ubicaciones.size(); i++){
            posX = ubicaciones.get(i).getCoordenadas().getxEnMapa();
            posY = ubicaciones.get(i).getCoordenadas().getyEnMapa();

            if(puntoCentrado.y+(posY+1)*escala>puntoFin.y) continue;
            if(puntoCentrado.x+(posX+1)*escala>puntoFin.x) continue;
            if(puntoCentrado.y+posY*escala<puntoInicio.y) continue;
            if(puntoCentrado.x+posX*escala<puntoInicio.x) continue;

            System.out.println("Ubicacion: "+ubicaciones.get(i).getIdUbicacion()+" ("+posX+";"+posY+")");
            g.setColor(color);
            g.fillRect(puntoCentrado.x+posX*escala, puntoCentrado.y+posY*escala, escala, escala);
//            g.setColor(Color.BLACK);
//            g.drawString(String.valueOf(ubicaciones.get(i).getIdUbicacion()), pto.x+posX*escala, pto.y+posY*escala+escala);
        }
    }

    public static void pintarMallaCOPIA(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, Point puntoCentrado,Point puntoInicio,Point puntoFin) {

        g.setColor(Color.BLACK);
        for(int i=0; i<=(puntoFin.y-puntoInicio.y)/escala; i++)//lineas horizontales
            g.drawLine(puntoInicio.x, puntoInicio.y+i*escala, puntoFin.x, puntoInicio.y+i*escala);

        for(int j=0; j<=(puntoFin.x-puntoInicio.x)/escala; j++)//lineas verticales
           g.drawLine(puntoInicio.x+j*escala, puntoInicio.y, puntoInicio.x+j*escala, puntoFin.y);
    }

    //Hace que la diferencia de los ejes entre dos puntos (osea p1.x-p2.x o p1.y-p2.y) sea un multiplo de la variable escala
    //Devuelve el punto ajustado
    public static Point AjustarPuntosSegunEscala(Point puntoFijo,Point puntoParaAjustar,int escala){
        int difX=(puntoParaAjustar.x-puntoFijo.x)/escala;
        int difY=(puntoParaAjustar.y-puntoFijo.y)/escala;

        puntoParaAjustar.x=puntoFijo.x+difX*escala;
        puntoParaAjustar.y=puntoFijo.y+difY*escala;

        return puntoParaAjustar;
    }

    public static void pintarSeccionesSegunColor(Graphics g, int racksPorCol, int racksPorFila, int tamanhoRack, int escala, ArrayList<beRack> racks, Point puntoInicio, Point puntoFin, Point puntoCentrado, Color color){
        for (int r=0;r<racks.size();r++){
            int x=2+((((beRack)racks.get(r)).getNumRack())-1)*(tamanhoRack+1);
            int y=racks.get(r).getNumFila();
            if ((y % 2) == 1){
                y = ((y+1)/2)*3-1;
            }
            else {
                y = (y/2)*3;
            }
            
            if(puntoCentrado.y+(y+1)*escala>puntoFin.y) continue;
            if(puntoCentrado.x+x*escala>=puntoFin.x) continue;
            if(puntoCentrado.y+y*escala<puntoInicio.y) continue;
            if(puntoCentrado.x+(x+tamanhoRack)*escala<=puntoInicio.x) continue;

            for(int j=0; j<tamanhoRack;j++){

                if(puntoCentrado.x+(x+j+1)*escala<=puntoInicio.x) continue;

                g.fillRect(x, y, escala*tamanhoRack, escala);

                g.setColor(color);
                g.fillRect(puntoCentrado.x+(x+j)*escala, puntoCentrado.y+y*escala, escala, escala);
                x++;
            }
        }
    }

    public static int transformarY(int y){
        if ((y % 2) == 1){
                y = ((y+1)/2)*3-1;
            }
        else {
                y = (y/2)*3;
        }

        return y;
    }
}
